using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;

namespace HslControls.Advanced
{
	public class NoBoundaryControl : UserControl
	{
		private Color graphiccolor = Color.FromArgb(168, 168, 168);

		private float[] scales = new float[17]
		{
			0.2f,
			0.3f,
			0.4f,
			0.5f,
			0.6f,
			0.7f,
			0.8f,
			0.9f,
			1f,
			1.1f,
			1.3f,
			1.5f,
			2f,
			2.5f,
			3f,
			4f,
			5f
		};

		private int scaleIndex = 8;

		private double offsetX = 0.0;

		private double offsetY = 0.0;

		private Point MouseCurrent = new Point(0, 0);

		private bool zoomEnable = true;

		private bool translationEnable = true;

		private bool isLeftMouseDown = false;

		private Point leftMouseDownPoint = default(Point);

		private int mouseDelta = 0;

		private Rectangle boundary = new Rectangle(0, 0, -100, -100);

		/// <summary> 
		/// 必需的设计器变量。
		/// </summary>
		private IContainer components = null;

		/// <summary>
		/// 用来显示画布的颜色
		/// </summary>
		[DefaultValue(typeof(Color), "168,168,168")]
		[Description("用来显示画布的颜色")]
		[Category("HslControls")]
		public Color GraphicColor
		{
			get
			{
				return graphiccolor;
			}
			set
			{
				graphiccolor = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置当前的控件是否允许缩放功能
		/// </summary>
		[DefaultValue(true)]
		[Description("获取或设置当前的控件是否允许缩放功能")]
		[Category("HslControls")]
		public bool ZoomEnable
		{
			get
			{
				return zoomEnable;
			}
			set
			{
				zoomEnable = value;
			}
		}

		/// <summary>
		/// 获取或设置当前的控件是否允许平移功能
		/// </summary>
		[DefaultValue(true)]
		[Description("获取或设置当前的控件是否允许平移功能")]
		[Category("HslControls")]
		public bool TranslationEnable
		{
			get
			{
				return translationEnable;
			}
			set
			{
				translationEnable = value;
			}
		}

		/// <summary>
		/// 获取或设置控件的前景色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置控件的前景色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "DimGray")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public override Color ForeColor
		{
			get
			{
				return base.ForeColor;
			}
			set
			{
				base.ForeColor = value;
			}
		}

		/// <summary>
		/// 获取或设置当前的控件的X轴的偏移信息
		/// </summary>
		[DefaultValue(0.0)]
		[Description("获取或设置当前的控件的X轴的偏移信息")]
		[Category("HslControls")]
		public int OffsetX
		{
			get
			{
				return (int)offsetX;
			}
			set
			{
				offsetX = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置当前的控件的Y轴的偏移信息
		/// </summary>
		[DefaultValue(0.0)]
		[Description("获取或设置当前的控件的Y轴的偏移信息")]
		[Category("HslControls")]
		public int OffsetY
		{
			get
			{
				return (int)offsetY;
			}
			set
			{
				offsetY = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 实例化一个默认的对象
		/// </summary>
		public NoBoundaryControl()
		{
			InitializeComponent();
			SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, value: true);
			SetStyle(ControlStyles.ResizeRedraw, value: true);
			SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
			SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
		}

		/// <inheritdoc />
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
		}

		/// <inheritdoc />
		protected override void OnMouseWheel(MouseEventArgs e)
		{
			if (zoomEnable)
			{
				double distanceX = 0.0;
				double distanceY = 0.0;
				float scale = scales[scaleIndex];
				if (e.Delta == 120)
				{
					if (scaleIndex >= scales.Length - 1)
					{
						return;
					}
					distanceX = (float)e.Location.X / scale - (float)e.Location.X / scales[scaleIndex + 1];
					distanceY = (float)e.Location.Y / scale - (float)e.Location.Y / scales[scaleIndex + 1];
					scaleIndex++;
				}
				else if (e.Delta == -120)
				{
					if (scaleIndex < 1)
					{
						return;
					}
					distanceX = (float)e.Location.X / scale - (float)e.Location.X / scales[scaleIndex - 1];
					distanceY = (float)e.Location.Y / scale - (float)e.Location.Y / scales[scaleIndex - 1];
					scaleIndex--;
				}
				mouseDelta = e.Delta;
				offsetX += distanceX;
				offsetY += distanceY;
				OffsetModInteger();
				base.OnMouseWheel(e);
				Invalidate();
			}
			else
			{
				base.OnMouseWheel(e);
			}
		}

		private void OffsetModInteger()
		{
			offsetX = Math.Round(offsetX, 0);
			offsetY = Math.Round(offsetY, 0);
		}

		/// <inheritdoc />
		protected override void OnMouseLeave(EventArgs e)
		{
			isLeftMouseDown = false;
			Cursor = Cursors.Arrow;
			base.OnMouseLeave(e);
		}

		/// <inheritdoc />
		protected override void OnMouseMove(MouseEventArgs e)
		{
			MouseCurrent = e.Location;
			if (translationEnable && isLeftMouseDown)
			{
				offsetX -= (float)(e.Location.X - leftMouseDownPoint.X) / scales[scaleIndex];
				offsetY -= (float)(e.Location.Y - leftMouseDownPoint.Y) / scales[scaleIndex];
				leftMouseDownPoint = e.Location;
			}
			base.OnMouseMove(e);
		}

		/// <inheritdoc />
		protected override void OnMouseUp(MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left)
			{
				isLeftMouseDown = false;
				Cursor = Cursors.Arrow;
				OffsetModInteger();
			}
			base.OnMouseUp(e);
		}

		/// <inheritdoc />
		protected override void OnMouseDown(MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left)
			{
				isLeftMouseDown = true;
				Cursor = Cursors.Hand;
				leftMouseDownPoint = e.Location;
			}
			base.OnMouseDown(e);
		}

		/// <inheritdoc />
		protected override void OnPaint(PaintEventArgs e)
		{
			if (Authorization.iashdiadasbdnajsdhjaf())
			{
				e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
				e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
				Graphics g = e.Graphics;
				g.Clear(graphiccolor);
				GraphicsTransform(g);
				base.OnPaint(e);
				g.ResetTransform();
				g.DrawString($"X:{offsetX:F0} Y:{offsetY:F0} Scale:{scales[scaleIndex]}", Font, Brushes.DimGray, new Point(5, base.Height - Font.Height - 2));
				Point point = ControlToActualPoint(MouseCurrent);
				g.DrawString($"CurrentX:{point.X} CurrentY:{point.Y}", Font, Brushes.DimGray, new Point(400, base.Height - Font.Height - 2));
			}
		}

		/// <summary>
		/// 将实际的坐标做换成控件的坐标
		/// </summary>
		/// <param name="point">实际的坐标</param>
		/// <returns>控件坐标</returns>
		public Point ActualToControlPoint(Point point)
		{
			Point infactPoint = default(Point);
			infactPoint.X = (int)(((double)point.X - offsetX) * (double)scales[scaleIndex]);
			infactPoint.Y = (int)(((double)point.Y - offsetY) * (double)scales[scaleIndex]);
			return infactPoint;
		}

		/// <summary>
		/// 将控件的坐标转换成实际的坐标
		/// </summary>
		/// <param name="point">控件坐标</param>
		/// <returns>实际坐标</returns>
		public Point ControlToActualPoint(Point point)
		{
			Point infactPoint = default(Point);
			infactPoint.X = (int)(offsetX + (double)((float)point.X / scales[scaleIndex]));
			infactPoint.Y = (int)(offsetY + (double)((float)point.Y / scales[scaleIndex]));
			return infactPoint;
		}

		/// <summary>
		/// 变换当前的图形到当前的缩放及偏移位置
		/// </summary>
		/// <param name="g">画图的对象</param>
		public void GraphicsTransform(Graphics g)
		{
			g.ResetTransform();
			g.ScaleTransform(scales[scaleIndex], scales[scaleIndex]);
			g.TranslateTransform((float)(0.0 - offsetX), (float)(0.0 - offsetY));
		}

		/// <summary>
		/// 设置支持的缩放等级及当前的缩放等级索引
		/// </summary>
		/// <param name="scales">缩放等级</param>
		/// <param name="index">当前的缩放索引</param>
		public void SetScales(float[] scales, int index)
		{
			if (scales != null)
			{
				this.scales = scales;
				if (index >= 0 && index < scales.Length)
				{
					scaleIndex = index;
				}
			}
		}

		/// <summary>
		/// 获取当前的缩放系数
		/// </summary>
		/// <returns>缩放系数</returns>
		public float GetScales()
		{
			return scales[scaleIndex];
		}

		/// <summary>
		/// 绘制指定的image对象到指定的位置，指定是否随地图缩放，旋转角度
		/// </summary>
		/// <param name="g">画刷句柄</param>
		/// <param name="location">位置</param>
		/// <param name="image">图形</param>
		/// <param name="noScale">是否缩放</param>
		/// <param name="angle">旋转角度</param>
		public void DrawImage(Graphics g, Point location, Bitmap image, bool noScale = true, float angle = 0f)
		{
			g.TranslateTransform(location.X, location.Y);
			g.RotateTransform(angle);
			if (image != null)
			{
				if (noScale)
				{
					int width = Convert.ToInt32((float)image.Width / GetScales());
					int height = Convert.ToInt32((float)image.Height / GetScales());
					g.DrawImage(image, new RectangleF(-width / 2, -height / 2, width, height));
				}
				else
				{
					g.DrawImage(image, new RectangleF(-image.Width / 2, -image.Height / 2, image.Width, image.Height));
				}
			}
			g.RotateTransform(0f - angle);
			g.TranslateTransform(-location.X, -location.Y);
		}

		/// <summary> 
		/// 清理所有正在使用的资源。
		/// </summary>
		/// <param name="disposing">如果应释放托管资源，为 true；否则为 false。</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		/// <summary> 
		/// 设计器支持所需的方法 - 不要修改
		/// 使用代码编辑器修改此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			SuspendLayout();
			base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
			ForeColor = System.Drawing.Color.DimGray;
			base.Name = "NoBoundaryControl";
			base.Size = new System.Drawing.Size(946, 594);
			ResumeLayout(false);
		}
	}
}
